Create:insert new records to the database
READ:Select or Search for records in the database
Update:Change some fields of the record in database
Delete:Remove records from the database
brew install sqlc
sqlc init
sqlc.yamlYou need to create folder : sqlc migration query
emit_json_tags : we want sqlc to add JSON tags to the generated structs
version: 1
packages:
- path: './db/sqlc'
name: 'db'
engine: 'postgresql'
schema: './db/migration'
queries: './db/query'
emit_json_tags: true
emit_prepared_queries: false
emit_interface: false
emit_exact_table_names: false
false
true, include support for prepared queries.optimize the database's performance.false
true, output a Querierquerier.go)mock database.false
true, struct names will mirror table names.
SQLCdb.go
// Code generated by sqlc. DO NOT EDIT.
// versions:
// sqlc v1.17.2
package db
import (
"context"
"database/sql"
)
type DBTX interface {
ExecContext(context.Context, string, ...interface{}) (sql.Result, error)
PrepareContext(context.Context, string) (*sql.Stmt, error)
QueryContext(context.Context, string, ...interface{}) (*sql.Rows, error)
QueryRowContext(context.Context, string, ...interface{}) *sql.Row
}
func New(db DBTX) *Queries {
return &Queries{db: db}
}
type Queries struct {
db DBTX
}
func (q *Queries) WithTx(tx *sql.Tx) *Queries {
return &Queries{
db: tx,
}
}
db, _ := sql.Open("driver", "dsn")
queries := New(db)
account, err := queries.CreateAccount(ctx, params)
db, _ := sql.Open("driver", "dsn")
queries := New(db)
tx, _ := db.Begin()
queriesWithTx := queries.WithTx(tx)
account, err := queriesWithTx.CreateAccount(ctx, params)
tx.Commit() // 或 tx.Rollback()
Makefilesqlc:
sqlc generate
Create:one Return one objectRETURNING * : return all record columnsdb/query/account.sql
-- name: CreateAccount :one
INSERT INTO accounts
(
owner,
balance,
currency
)
VALUES
(
$1, $2, $3
)
RETURNING *;
func (q *Queries) CreateAccount(ctx context.Context, arg CreateAccountParams) (Account, error) {
// 使用 q.db.QueryRowContext 方法執行 SQL 查詢,傳入 SQL 命令和參數
row := q.db.QueryRowContext(ctx, createAccount, arg.Owner, arg.Balance, arg.Currency)
// 創建一個 Account 類型的變量 i,用於存放查詢結果
var i Account
// 使用 row.Scan 方法將查詢結果映射到 i 的相應字段
// 通過傳入指針,row.Scan 會直接修改 i 的值
err := row.Scan(
&i.ID, // 將查詢結果的 ID 存放到 i.ID
&i.Owner, // 將查詢結果的 Owner 存放到 i.Owner
&i.Balance, // 將查詢結果的 Balance 存放到 i.Balance
&i.Currency, // 將查詢結果的 Currency 存放到 i.Currency
&i.CreatedAt, // 將查詢結果的 CreatedAt 存放到 i.CreatedAt
)
// 返回 Account 類型的 i 和可能的錯誤 err
return i, err
}
make sqlc
sqlc generate
models.go : struct definition of models (Account、Entry、Transfer)db.go : contain dbtx interfaceaccount.sql.go : account.sql's Query Functionstree db/sqlc
db/sqlc
├── account.sql.go
├── db.go
└── models.go
ReadGetAccount : Only get one accountListAccounts : Get all accountsOFFSET : 從LIMIT+1 開始回傳幾筆Data(用於分頁)db/query/account.sql
- name: GetAccount :one
SELECT *
FROM accounts
WHERE id = $1
LIMIT 1;
-- name: ListAccounts :many
SELECT *
FROM accounts
ORDER BY id
LIMIT $1
OFFSET $2;
Update:one Return one objectRETURNING * : return all record columnsdb/query/account.sql
-- name: UpdateAccount :one
UPDATE accounts SET balance = $2
WHERE id = $1
RETURNING *;
Deletedb/query/account.sql
-- name: DeleteAccount :exec
DELETE FROM accounts WHERE id = $1;
Entry
/*
one: returns a single record
many: returns multiple record
RETURNING * : return all record columns
*/
-- name: CreateEntry :one
INSERT INTO entries
(
account_id,
amount
)
VALUES
(
$1, $2
)
RETURNING *;
-- name: GetEntry :one
SELECT *
FROM entries
WHERE id = $1
LIMIT 1;
/*
GetEntries returns all entries for a given account
*/
-- name: ListEntries :many
SELECT *
FROM entries
WHERE account_id = $1
ORDER BY id
LIMIT $2
OFFSET
$3;
Transfer
/*
one: returns a single record
many: returns multiple record
RETURNING * : return all record columns
*/
-- name: CreateTransfer :one
INSERT INTO transfers
(
from_account_id,
to_account_id,
amount
)
VALUES
(
$1, $2, $3
)
RETURNING *;
-- name: GetTransfer :one
SELECT *
FROM transfers
WHERE id = $1
LIMIT 1;
-- name: ListTransfers :many
SELECT *
FROM transfers
WHERE from_account_id = $1 OR to_account_id = $2
ORDER BY id
LIMIT $3
OFFSET
$4;